﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace Home.Haushalt.Gui
{
    /// <summary>
    /// 
    /// </summary>
    public class HWebBrowser : WebBrowser
    {
        /// <summary>
        /// 
        /// </summary>
        public class FormInputEventArgs : EventArgs
        {
            /// <summary></summary>
            public HtmlElement HtmlForm;
            /// <summary></summary>
            public string FormName = "";
            /// <summary></summary>
            public string FormString = "";

            /// <summary>
            /// 
            /// </summary>
            public FormInputEventArgs() { }

            /// <summary>
            /// 
            /// </summary>
            /// <param name="formName"></param>
            /// <param name="htmlForm"></param>
            /// <param name="formString"></param>
            public FormInputEventArgs(string formName, HtmlElement htmlForm, string formString)
            {
                FormName = formName;
                HtmlForm = htmlForm;
                FormString = formString;
            }
        }

        /// <summary></summary>
        public event EventHandler<FormInputEventArgs> OnFormInput;

        /// <summary>Forms, die der Benutzer ausgefüllt hat </summary>
        public List<string> InputForms = new List<string>();

        /// <summary></summary>
        private SortedList<string, HtmlElement> HtmlForms = new SortedList<string, HtmlElement>();

        /// <summary></summary>
        private bool _documentParseMode = false;
        /// <summary>Z.B. für Autologin</summary>
        public bool DocumentParseMode
        {
            get { return _documentParseMode; }
            set { _documentParseMode = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public HWebBrowser()
        {
            this.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(Browser_DocumentCompleted);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            if (this.ReadyState == WebBrowserReadyState.Complete)
            {
                if (_documentParseMode)
                {
                    HtmlForms.Clear();
                    InputForms.Clear();

                    InitForm();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void InitForm()
        {
            foreach (HtmlElement form in this.Document.Forms)
            {
                string formName = form.GetAttribute("name");
                if (formName.Trim().Length == 0 || HtmlForms.ContainsKey(formName))
                {
                    formName = "form" + Guid.NewGuid().ToString().Replace("-", "");
                    form.SetAttribute("name", formName);
                }

                HtmlForms.Add(formName, form);

                foreach (HtmlElement he in form.GetElementsByTagName("input"))
                {
                    he.KeyUp += new HtmlElementEventHandler(he_KeyDown);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void he_KeyDown(object sender, HtmlElementEventArgs e)
        {
            if (_documentParseMode)
            {
                HtmlElement form = GetForm((HtmlElement)sender);

                if (form != null)
                {
                    if (HtmlForms.ContainsKey(form.Name))
                    {
                        if (!InputForms.Contains(form.Name))
                        {
                            InputForms.Add(form.Name);
                        }

                        if (OnFormInput != null)
                            OnFormInput(this, new FormInputEventArgs(form.Name, form, FormToString(form)));
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="control"></param>
        /// <returns></returns>
        private HtmlElement GetForm(HtmlElement control)
        {
            if (control.Parent != null)
            {
                if (control.Parent.TagName.ToUpper() == "FORM")
                {
                    return control.Parent;
                }
                else
                {
                    return GetForm(control.Parent);
                }
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="formName"></param>
        /// <returns></returns>
        public string GetForm(string formName)
        {
            if (HtmlForms.ContainsKey(formName))
            {
                return FormToString(HtmlForms[formName]);
            }
            return "";
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        internal string FormToString(HtmlElement form)
        {
            string result = "";
            result = "<html><body>";
            result += "<b>Anmeldung folgt...</b>";

            string formName = form.GetAttribute("name");

            string formMethod = form.GetAttribute("method");
            string formAction = form.GetAttribute("action");

            if (formAction.IndexOf("://") == -1)
            {
                formAction = this.Url.ToString().Trim(new char[] { '/' }) + "/" + formAction;
            }

            result += "<form name=\"" + formName + "\" action=\"" + formAction + "\" method=\"" + formMethod + "\">";
            foreach (HtmlElement he in form.GetElementsByTagName("input"))
            {
                string controlType = he.GetAttribute("type").ToUpper();

                if (controlType == "TEXT" || controlType == "PASSWORD" || controlType == "HIDDEN" || controlType == "SUBMIT")
                {
                    string controlName = he.GetAttribute("name");
                    string controlValue = he.GetAttribute("value");

                    result += "<input type=\"HIDDEN\" name=\"" + controlName + "\" value=\"" + controlValue + "\"/>";
                }
            }
            result += "<script language=\"JavaScript\">" + formName + ".submit();</script>";
            result += "</form>";
            result += "</body></html>";

            return result;
        }

    }

}
